﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using GeoCoderParser;
using GeoUtils;

namespace GeoCoderConsole
{
    class Program
    {
        static public string OutputResult(GeoCoderParser.GeoCoderResult geoCoderResult, ref string strWhat)
        {
            List<LatLong> latLongList = new List<LatLong>();

            strWhat = "";
            if (geoCoderResult.tokenList != null)
            {
                foreach (GeoUtils.Token token in geoCoderResult.tokenList)
                {
                    if (token.geoEntity != null && token.tknSubGeoList.Count == 0)
                    {
                        latLongList.Add(token.geoEntity.LatLong);
                    }

                    string strFullAddress = geoCoderResult.GetFullAddress(token.geoEntity);
                    if (token.strTagList.Count > 0)
                    {
                        string strTags = "";
                        foreach (string strTag in token.strTagList)
                        {
                            strTags = strTags + "|" + strTag;
                        }
                        strTags = strTags.Substring(1);     
                        strWhat = strWhat + token.strTerm + "[" + strTags + ":" + strFullAddress + "] ";
                    }
                    else
                    {
                        strWhat = strWhat + token.strTerm + "[NOR] ";
                    }
                }
            }

            string strWhere = "";
            if (latLongList.Count > 0)
            {
                strWhere = "(" + latLongList[0].Latitude.ToString() + "," + latLongList[0].Longitude.ToString() + ")";
            }
            return strWhere;
        }

        static void Main(string[] args)
        {
            if (args.Length != 4)
            {
                Console.WriteLine("GeoCoder [Ranking Model Type] [Geography coder data path] [input file] [output file]");
                Console.WriteLine("Ranking Model Type:");
                Console.WriteLine("   NORM_LTR - ranking geo-entity candidates by machine learning based algorithm");
                Console.WriteLine("   NORM_RULE - ranking geo-entity candidates by rule based algorithm");
                return;
            }

            //Parse ranking mode type:NORM_LTR, NORM_RULE
            string strRankModeType = args[0].ToUpper();

            //Initialize the parser
            if (Directory.Exists(args[1]) == false)
            {
                Console.WriteLine("FAILED: {0} is not existed.", args[1]);
                return;
            }
            GeoCoderParser.AddressParser parser = new GeoCoderParser.AddressParser();
            parser.Initialize(args[1]);

            GeoCoderParser.GeoCoderResult geoCoderResult;

            StreamReader sr = new StreamReader(args[2], Encoding.UTF8);
            StreamWriter sw = new StreamWriter(args[3], false, Encoding.UTF8);
            
            while (sr.EndOfStream == false)
            {
                string strLine = sr.ReadLine();
                //strLine = "上海 长宁区 杨宅路278号	39.911762	116.379234";

                string[] items = strLine.Split('\t');
                string strQuery = items[0];

                double fX = double.Parse(items[1]);
                double fY = double.Parse(items[2]);
                LatLong latLong = new LatLong(fX, fY);
                ViewPort viewPort = null;
                GeoEntity region;
                region = parser.FindRegion(latLong);
                if (region != null)
                {
                    viewPort = new ViewPort(region.BoundingRect, latLong);
                }

                //Call address parser
                string strWhere = "", strWhat = "";
                parser.SetRunMode(strRankModeType);
                geoCoderResult = parser.Parse(strQuery, viewPort);
                strWhere = OutputResult(geoCoderResult, ref strWhat);
                sw.WriteLine("{0}\t{1}\t{2}", strQuery, strWhere, strWhat);
            }

            sr.Close();
            sw.Close();
        }
    }
}
